Day 7 我們加入 Cache,減少大量重複的 Database Read。
但 Cache Miss、User-specific Query、Frequently Changing Data
最後仍可能需要讀 Database。
假設:
Read = 100,000 requests/sec
Write = 1,000 requests/sec
所有 Traffic 都集中到同一台 Database,它仍然可能成為 Bottleneck。
今天的問題是:
能不能增加更多 Database Server 來分擔 Read Traffic?
答案之一就是:
Database Replication
Replication 可以簡單理解成:
把一台 Database 的資料複製到其他 Database Server。
Primary
│
┌──────┼──────┐
↓ ↓ ↓
Replica 1 Replica 2 Replica 3
Primary 的資料會被複製到 Replica。
常見分工:
WRITE → Primary
READ → Replica
這種概念稱為:
Read / Write Splitting
原本:
100,000 Reads/sec
↓
Database
加入多台 Read Replica:
┌── Replica #1
100,000 Reads ────┼── Replica #2
└── Replica #3
Read Traffic 可以分散。
核心概念:
不要讓所有 Read 都集中在 Primary。
┌── Backend #1
│
User → Load Balancer ────┼── Backend #2
│
└── Backend #3
│
Cache
│
┌───────────┴───────────┐
│ │
Write Read
↓ ↓
Primary Read Replicas
┌── Replica #1
├── Replica #2
└── Replica #3
到目前為止,我們已經有:
Load Balancer
Multiple Backend Servers
Cache
Primary Database
Read Replicas
但每加入一個 Component,都會帶來新的 Trade-off。
假設 Primary 執行:
UPDATE products
SET price = 899
WHERE id = 123;
Primary 已經:
Price = $899
但 Change 還需要傳到 Replica:
Primary
│
├──→ Replica #1
├──→ Replica #2
└──→ Replica #3
Replication 需要時間。
這段 Primary 與 Replica 暫時不同步的 Delay:
Replication Lag
假設 User 修改:
Alvin → Wei-Hong
Write:
Backend → Primary
Primary 已經:
Wei-Hong
User 馬上 Refresh。
Read:
Backend → Replica
但 Replica 還沒同步:
Replica → Alvin
所以 User 可能看到舊資料。
這就是:
Replication Lag
↓
Stale Read
User 通常期待:
我剛寫入的資料,下一次 Read 應該看得到。
這就是:
Read-After-Write Consistency
但:
Write → Primary
Read → Replica
如果 Replica 有 Lag,就可能無法立刻做到。
一種策略:
User 剛完成 Write
↓
短時間 Read Primary
↓
Replica Catch Up
↓
之後 Read Replica
但這又帶來 Routing Complexity。
System Design 永遠是:
Requirement
↓
Solution
↓
Trade-off
Synchronous Replication 簡化理解:
Client
↓
Primary
↓
Replica
↓
Replica ACK
↓
Primary 回 Success
優點:
Replica Freshness 較高
Data Loss Risk 通常較低
缺點:
Write Latency ↑
Replica Slow → Write 可能被拖慢
Asynchronous Replication:
Client
↓
Primary
↓
Write Success
↓
Response
↓
之後 Replicate
優點:
Write Latency 較低
Primary 不需要等待 Replica
缺點:
Replication Lag
Stale Reads
Potential Data Loss
簡單比較:
Synchronous Asynchronous
Write Latency 較高 較低
Replica Freshness 較高 可能 Lag
Primary 等 Replica 是 通常否
Data Loss Risk 通常較低 可能較高
核心:
Replication Strategy 是 Consistency、Latency、Availability 的
Trade-off。
如果 Database A:
Price → $899
同時 Database B:
Price → $799
最後應該是哪個?
$899?
$799?
這會產生:
Write Conflict
Ordering
Consistency
Conflict Resolution
所以很多常見 Architecture 會使用:
Single Primary
Multiple Replicas
也存在 Multi-Primary、Leaderless 等設計,但 Complexity 更高。
Primary ❌
│
┌──────┼──────┐
↓ ↓ ↓
Replica 1 Replica 2 Replica 3
如果所有 Write 都需要 Primary:
Write ❌
一個重要解法:
Promote Replica
Replica #1
↓
Promote
↓
New Primary
這個過程稱為:
Failover
系統可以:
Health Check
↓
Primary Down?
↓
Select Replica
↓
Promote
↓
Redirect Traffic
這可以提升:
Availability
但 Failover 並不簡單。
假設 Old Primary 只是因為 Network Partition 暫時無法聯絡。
系統 Promote 另一台 Replica。
現在:
Old Primary
+
New Primary
兩邊都認為自己可以接受 Write。
可能造成:
Data Conflict
這類問題稱為:
Split Brain
真正的 Failover 可能涉及:
Leader Election
Quorum
Consensus
Fencing
Day 8 先記住:
Failover 不是 Primary 掛掉後隨便選一台 Replica 就完成了。
不行。
假設有人執行:
DELETE FROM users;
Replication 可能把這個 Delete 同樣複製到 Replica:
Primary → Deleted
Replica → Deleted
所以:
Replication
主要解決:
Read Scaling
Availability
Failover
而:
Backup
主要解決:
Historical Restore
Accidental Deletion
Disaster Recovery
所以:
High Availability 不等於 Disaster Recovery。
這是很常混淆的觀念。
DB #1 → A B C D
DB #2 → A B C D
DB #3 → A B C D
每台大致保存:
Same Data
主要目的:
Read Scaling
Availability
Redundancy
Shard #1 → Users 1 - 1M
Shard #2 → Users 1M - 2M
Shard #3 → Users 2M - 3M
每台保存:
Different Subset of Data
主要目的:
Split Data
Scale Storage
Scale Write
簡單記:
Replication → Copy the data
Sharding → Split the data
Cache:
Backend → Redis
通常是:
Frequently Accessed Data
Temporary Copy
Very Fast Access
Read Replica:
Backend → Replica
通常保存 Database 的資料副本。
Cache 偏向:
Reduce Latency
Reduce Repeated Queries
Replication 偏向:
Read Scaling
Availability
Redundancy
兩個可以一起使用:
Backend
↓
Cache
↓ Cache Miss
Read Replica
假設:
系統有 100,000 Reads/sec,但只有 1,000 Writes/sec,Database 已經成為
Bottleneck,怎麼改善?
先分析:
Read >> Write
可能先使用:
Cache
如果仍有大量 DB Reads:
Read Replicas
Architecture:
┌── Replica #1
Backend → Cache Miss ────┼── Replica #2
└── Replica #3
Backend → Write ───────────→ Primary
接著主動說明:
Replication Lag
Stale Read
Failover
Consistency
這樣就不是只會背:
Read Replica = Faster
而是能解釋 Solution 的 Trade-off。
情境:
User Update Name
Alvin → Wei-Hong
Write:
Backend → Primary
接著 Refresh:
Backend → Replica
Replica 還沒同步。
結果:
Alvin
原因:
Replication Lag
改善方向可以討論:
Read from Primary after Write
Wait for Replication
Session-based Routing
Version / Position Tracking
每種方法都有:
Latency
Complexity
Scalability
Trade-off。
Backend 怎麼知道:
SELECT → Replica
INSERT → Primary
Application 可能使用:
Separate DB Connections
Database Proxy
ORM Routing
Service Layer
概念:
┌── WRITE → Primary
Backend ────┤
└── READ → Replica Pool
但不是所有 Read 都一定適合 Replica。
例如:
Read-after-write
Strong Consistency Required
Critical Transaction
可能仍然需要 Primary。
所以 Routing 要看:
Consistency Requirement
假設:
Read = 100,000/sec
Write = 100,000/sec
Read Replica 可以分擔 Read。
但 Write 還是:
All Writes
↓
Primary
Primary 仍可能成為 Write Bottleneck。
另一個問題:
10 TB
↓
50 TB
↓
100 TB
Replication 是 Copy Data。
每台仍然需要保存大量相同資料。
如果真正需要:
Split Data
Scale Storage
Scale Write
就會開始考慮:
Sharding
我們不是一開始就加入所有 Technology。
而是:
Traffic increases
↓
Find Bottleneck
↓
Choose Solution
↓
Understand Trade-off
↓
Find Next Bottleneck
目前 Architecture 已經從:
User → Server → Database
進化成:
User
↓
Load Balancer
↓
Backend Servers
↓
Cache
↓
Read Replicas / Primary
這才是 System Design 真正重要的思考方式。
1. Database Replication 是什麼?
2. Primary 和 Replica 有什麼差別?
3. Read / Write Splitting 是什麼?
4. 為什麼 Read Replica 可以提升 Read Scalability?
5. Replication Lag 是什麼?
6. 為什麼 User 更新資料後可能看到舊資料?
7. Read-After-Write Consistency 是什麼?
8. Synchronous Replication 是什麼?
9. Asynchronous Replication 是什麼?
10. Sync vs Async 的 Trade-off?
11. Primary 掛掉怎麼辦?
12. Failover 是什麼?
13. Split Brain 是什麼?
14. Replication 可以取代 Backup 嗎?
15. Replication vs Backup?
16. Replication vs Sharding?
17. Cache vs Read Replica?
18. 哪些 Read 可能需要走 Primary?
19. Write-heavy System 中 Read Replica 能解決主要 Bottleneck 嗎?
20. 100,000 Reads/sec、1,000 Writes/sec 的 Database 怎麼 Scale?
如果能用自己的話回答這些問題,就開始真正理解:
Scalability
Consistency
Availability
Fault Tolerance
Trade-off
Replication 核心:
Primary
↓
Replicate Data
↓
Replicas
常見分工:
Write → Primary
Read → Replica
它可以改善:
Read Scaling
Availability
Fault Tolerance
但也帶來:
Replication Lag
Stale Reads
Failover Complexity
Consistency Problems
最重要的一句:
Replication 用資料副本與額外的 Consistency Complexity,換取 Read
Scalability 與 Availability。
Replication:
Primary → 10 TB
Replica → 10 TB
Replica → 10 TB
每台仍然保存大量相同 Data。
如果資料增加:
10 TB → 50 TB → 100 TB
或者 Write Traffic 越來越高:
All Writes → Primary
Primary 還是可能成為 Bottleneck。
下一步就是:
把資料本身拆開。
下一篇:
Day 9|Database Sharding:資料太多,一台 Database 放不下怎麼辦?
我們會開始了解:
Shard
Shard Key
Horizontal Partitioning
Hash-based Sharding
Range-based Sharding
Rebalancing
Hot Shard
Cross-shard Query
以及面試常見問題:
User Data 怎麼分到不同 Shard?
Shard Key 選錯會怎樣?
為什麼 country 可能不是好的 Shard Key?
JOIN 跨 Shard 怎麼辦?
新增 Shard 後資料怎麼重新分配?
Replication 和 Sharding 可以一起用嗎?
Architecture 會繼續進化:
Shard #1 → Primary + Replicas
Shard #2 → Primary + Replicas
Shard #3 → Primary + Replicas
開始進入大型 Distributed Database 的世界。